package com.cyanite.playlv2;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import com.cyanite.playlv2.R;
import com.cyanite.playlv2.util.NotificationsUtil;
import com.cyanite.playlv2.widget.SegmentedButton;
import com.cyanite.playlv2.widget.SegmentedButton.OnClickListenerSegmentedButton;
import com.cyanite.playlv2api.PlayLv2Api;
import com.cyanite.playlv2api.types.Response;
import com.cyanite.playlv2api.util.ConstantsUtils;
import com.cyanite.playlv2.widget.DataBaseAdapter;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.InputFilter;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

public class TripCreateSceneryActivity extends Activity {

    private StateHolder mStateHolder;
    private ProgressDialog mDlgProgress;
    private Calendar mCalendar;
    private EditText mSceneryTitle;
    private TextView mTotalDays;
    private AutoCompleteTextView mStartpoint;
    private AutoCompleteTextView mEndpoint;
    private DatePicker mDatePicker;
    private LinearLayout mLinearLayout;
    private PopupWindow mPopup;
    private TextView mPopupText;
    private LayoutInflater mInflater;
    private int mYear = 0;
    private int mMonth = 0;
    private int mDay = 0;
    private String mDate;
    private int mDayNeeded = 1;
    private ArrayList<String> mSceneryList;
    private static final int MAX_DAY = 29;

    private BroadcastReceiver mLoggedOutReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    };

	public void onCreate(Bundle savedInstanceState)	{
		super.onCreate(savedInstanceState);
		registerReceiver(mLoggedOutReceiver, new IntentFilter(PlayLv2.INTENT_ACTION_LOGGED_OUT));
		setTheme(android.R.style.Theme);
        setContentView(R.layout.trip_create_scenery_activity);		

        mStateHolder = new StateHolder();
        ensureUi();
	}

	private boolean compareAddressName(String name){
	    for( int i=0; i < mSceneryList.size(); i++ ){
	        if (name.equalsIgnoreCase(mSceneryList.get(i))){
	            return true;
	        }
	    }
	    return false;
	}

	@Override
    public void onResume() {
        super.onResume();
        ((PlayLv2) getApplication()).requestLocationUpdates(true);
    }

	@Override
    public void onPause() {
        super.onPause();
        stopProgressBar();
    }

	@Override
    public void onDestroy() {
        super.onDestroy();
        stopProgressBar();
        unregisterReceiver(mLoggedOutReceiver);
    }

	private void ensureUi()    {
	    setTitle(getString(R.string.trip_create_scenery_activity_label));
	    
	    mInflater = LayoutInflater.from(this);
        mLinearLayout = (LinearLayout)findViewById(R.id.llHeader);
        mSceneryList = (((PlayLv2) getApplication())).getDBList();
        if (mSceneryList == null) {           
            try   {
                DataBaseAdapter db = new DataBaseAdapter(this);
                db.open();
                mSceneryList = new ArrayList<String>();
                db.getCityList(mSceneryList);
                db.getPlacesList(mSceneryList);
                db.close();
            }
            catch(Exception ex) {
            }
        }

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, mSceneryList );
        mStartpoint = (AutoCompleteTextView)findViewById(R.id.tvStartpoint);
        mStartpoint.setAdapter(adapter);
        mEndpoint = (AutoCompleteTextView)findViewById(R.id.tvEndpoint);
        mEndpoint.setAdapter(adapter);
        mSceneryTitle = (EditText)findViewById( R.id.etSceneyTitle );
        mSceneryTitle.setFilters(new InputFilter[]{new InputFilter.LengthFilter(20)});

        mDatePicker = (DatePicker)findViewById(R.id.Datepicker);
        mCalendar = Calendar.getInstance();
        mYear = mCalendar.get(Calendar.YEAR);
        mMonth = mCalendar.get(Calendar.MONTH);
        mDay = mCalendar.get(Calendar.DAY_OF_MONTH);
        mDatePicker.init(mYear,mMonth,mDay, new DatePicker.OnDateChangedListener() {
            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)    {
                monthOfYear++;
                int myear = mCalendar.get(Calendar.YEAR);
                int mon = mCalendar.get(Calendar.MONTH) + 1;
                int day = mCalendar.get(Calendar.DAY_OF_MONTH);
                Date currentDate = new Date(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH)+1, mCalendar.get(Calendar.DAY_OF_MONTH));

                if (currentDate.compareTo(new Date(year,monthOfYear,dayOfMonth)) > 0){
                    Toast.makeText(TripCreateSceneryActivity.this, 
                            getString(R.string.trip_create_invalidate_date_note), Toast.LENGTH_LONG).show();
                    mDatePicker.updateDate(myear, mon-1, day);
                    return;
                }
                mYear = year;
                mMonth = monthOfYear;
                mDay = dayOfMonth;
            }
        });

        Button btnCreate = (Button)findViewById( R.id.btnCreate );
        btnCreate.setOnClickListener(new Button.OnClickListener(){
            public void onClick(View v){
                String title = mSceneryTitle.getText().toString();
                mDate = String.format(TripCreateSceneryActivity.this.getString(R.string.trip_date), mYear, mMonth, mDay);
                if ( title.length() != 0 && mDate.length() != 0 )   {
                    popUpAlertDialog(TripCreateSceneryActivity.this,String.format(TripCreateSceneryActivity.this.getString(R.string.trip_create_scenery_note),mDayNeeded));
                }   else if (title.equalsIgnoreCase("")){
                    Toast.makeText(TripCreateSceneryActivity.this,TripCreateSceneryActivity.this.getString(R.string.trip_title).substring(0, 4)+TripCreateSceneryActivity.this.getString(R.string.trip_alert_info), Toast.LENGTH_LONG).show();
                }  else if(mDate.equalsIgnoreCase("")){
                    Toast.makeText(TripCreateSceneryActivity.this, TripCreateSceneryActivity.this.getString(R.string.trip_start_time)+TripCreateSceneryActivity.this.getString(R.string.trip_alert_info), Toast.LENGTH_LONG).show();
                }
            }
        });

        SegmentedButton btnChooseTrip = (SegmentedButton)findViewById(R.id.btnChooseTrips);
        btnChooseTrip.clearButtons();
        btnChooseTrip.addButtons(getString(R.string.trip_follow_team), getString(R.string.trip_by_self));
        btnChooseTrip.setOnClickListener(new OnClickListenerSegmentedButton() {
            @Override
            public void onClick(int index) {
                switch(index){
                    case 0:
                        mStateHolder.setTripType(ConstantsUtils.TripTypeConsts.TRIP_TYPE_PARTY);
                        break;
                    case 1:
                        mStateHolder.setTripType(ConstantsUtils.TripTypeConsts.TRIP_TYPE_SELF);
                        break;
                    default:
                        break;
                }
            }
        });

        mTotalDays = (TextView)findViewById(R.id.tvTotalDays);
        SeekBar totalDaysSB = (SeekBar)findViewById(R.id.skTotalDays);
        totalDaysSB.setMax(MAX_DAY);
        mTotalDays.setText(String.valueOf(mDayNeeded) + getString(R.string.trip_total_days_tag));
        totalDaysSB.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mPopup.dismiss();
                mTotalDays.setText(String.valueOf(mDayNeeded) + getString(R.string.trip_total_days_tag));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Context context = TripCreateSceneryActivity.this;
                PopupWindow popup = mPopup;
                if ( popup == null ) {
                    mPopupText = (TextView) mInflater.inflate(R.layout.popup_text, null);
                    float scale = context.getResources().getDisplayMetrics().density;
                    popup = new PopupWindow(mPopupText, (int) (70*scale), (int) (56*scale));
                    popup.setBackgroundDrawable(context.getResources().getDrawable(android.R.drawable.alert_dark_frame));
                    popup.setContentView(mPopupText);
                    mPopup = popup;
                }
                Rect rect = new Rect();
                mDatePicker.getGlobalVisibleRect(rect);
                int xoff = (rect.right - popup.getWidth() )/2;
                int yoff = rect.top;
                popup.showAsDropDown(mLinearLayout, xoff, -yoff);
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mTotalDays.setText("");
                mDayNeeded = progress;
                mPopupText.setText(String.valueOf(++mDayNeeded) + getString(R.string.trip_total_days_tag));
            }
        });
	}

	public boolean onKeyDown(int keyCode, KeyEvent event)  {
        if (keyCode == KeyEvent.KEYCODE_BACK){
            startActivity(new Intent(TripCreateSceneryActivity.this, TripCreateMainActivity.class));
            finish();
            return true;
        }
        return false;
    }

	public void popUpAlertDialog(Context context,String str)   {
	    AlertDialog dlg = new AlertDialog.Builder(this)
        .setTitle(context.getString(R.string.trip_alert))
        .setMessage(str)
        .setPositiveButton(context.getString(R.string.ok),
        new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int whichButton){
            mStateHolder.startTaskCreateTrip(
                                    TripCreateSceneryActivity.this,
                                    new String[] {
                                            mSceneryTitle.getText().toString(),
                                            mStartpoint.getText().toString(),
                                            mEndpoint.getText().toString(),
                                            mDate,
                                            ConstantsUtils.TripTypeConsts.tripTypeS[mStateHolder.getTripType()],
                                            String.valueOf(mDayNeeded)
                                            });
            }
        }).setNegativeButton(context.getString(R.string.cancel),
        new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int whichButton){
            }
        }).create();
        dlg.show();
    }

	private void startProgressBar() {
        if (mDlgProgress == null) {
            mDlgProgress = ProgressDialog.show(this, null, getResources().getString(R.string.trip_create_progress_bar_message));
        }
        mDlgProgress.show();
    }

    private void stopProgressBar() {
        if (mDlgProgress != null) {
            mDlgProgress.dismiss();
            mDlgProgress = null;
        }
    }
    
    private void createTripTaskComplete(Response response, Exception ex) {
        stopProgressBar();
        if (response != null && Integer.valueOf(response.getValue()) > 0) {
            Toast.makeText(TripCreateSceneryActivity.this, getString(R.string.trip_create_success_toast),
                    Toast.LENGTH_LONG).show();

            // now loop into add follows activity
            Intent intent = new Intent(TripCreateSceneryActivity.this, AddFollowsActivity.class);
            intent.putExtra(AddFollowsActivity.EXTRA_TRIP_ID, response.getValue());
            startActivity(intent);
            finish();
        }   else {
            // Error, let them hang out here.
            NotificationsUtil.ToastReasonForFailure(this, ex);
        }
    }
    
	private static class CreateTripTask extends AsyncTask<Void, Void, Response> {

        private TripCreateSceneryActivity mActivity;
        private String[] mParams;
        private Exception mReason;

        public CreateTripTask(TripCreateSceneryActivity activity,
                                              String[] params) {
            mActivity = activity;
            mParams = params;
        }

        @Override
        protected void onPreExecute() {
            mActivity.startProgressBar();
        }

        @Override
        protected Response doInBackground(Void... params) {
            try {
                PlayLv2Api playlv2api = ((PlayLv2)mActivity.getApplication()).getPlayLv2Api();
                Response response = playlv2api.createTrip(mParams[0], // title
                                                                mParams[1], // startpoint
                                                                mParams[2], // endpoint
                                                                mParams[3], // starttime,
                                                                mParams[4], // type
                                                                mParams[5]);    // days
                if (response == null)   response = new Response();
                return response;
                    } catch (Exception ex) {
                mReason = ex;
                return null;
            }
        }

        @Override
        protected void onPostExecute(Response response) {
            if (mActivity != null) {
                mActivity.createTripTaskComplete(response, mReason);
            }
        }

        @Override
        protected void onCancelled() {
            if (mActivity != null) {
                mActivity.createTripTaskComplete(null, mReason);
            }
        }
    }

	private static class StateHolder {

	    private CreateTripTask mTaskCreateTrip;
	    private int mTripType;

        public StateHolder() {
        }

        public int getTripType() {
            return mTripType;
        }

        public void setTripType(int type)    {
            mTripType = type;
        }

        public void startTaskCreateTrip(TripCreateSceneryActivity activity, String[] params) {
            mTaskCreateTrip = new CreateTripTask(activity, params);
            mTaskCreateTrip.execute();
        }        
    }
}
